﻿namespace BitmapFontCreator
{

	#region Using

	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Data;
	using System.Drawing;
	using System.Text;
	using System.Windows.Forms;
	using System.Drawing.Text;
	using System.Drawing.Imaging;

	#endregion Using
	
	/// <summary>
	/// Main form for creating bitmap fonts
	/// </summary>
	public partial class FontCreatorMain : Form
	{

		#region Constructor

		/// <summary>
		/// Constructor
		/// </summary>
		public FontCreatorMain()
		{
			InitializeComponent();
			InitializeFonts();

			this.btClose.Click += delegate { Application.Exit(); };
			this.btGenerate.Click += delegate { this.GenerateBitmapFont(); };
		}

		#endregion Constructor

		#region Methods

		/// <summary>
		/// This method generates preview of bitmap font in the label
		/// </summary>
		private Bitmap GeneratePreview()
		{
			bool shadow = this.cbShadow.Checked;
			SolidBrush solidBack = new SolidBrush(this.button1.BackColor);

			int start = 33;
			int end = 255;
			int letterWidth = (int)this.nuLetterSize.Value;
			int letterHeigth = (int)this.nuLetterHeight.Value;
			Bitmap bmp = new Bitmap(letterWidth * (end - start), letterHeigth);
			try
			{
				Graphics gp = Graphics.FromImage(bmp);
				Font font = new Font(this.cbFonts.SelectedItem as FontFamily, (int)nuFontSize.Value);

				gp.Clear(Color.Transparent);
				gp.TextRenderingHint = TextRenderingHint.AntiAlias;
				for (int i = start; i <= end; ++i)
				{
					int pos = (i - start) * letterWidth;
					if (shadow)
					{
						for (int x = -2; x < 2; ++x)
						for (int y = -2; y < 2; ++y)
						{
							gp.DrawString(((char)i).ToString(), font, solidBack, new PointF(pos + x, 4 + y));
						}
					}
					
					gp.DrawString(((char)i).ToString(), font, Brushes.White, new PointF(pos, 3));
				}
			}
			catch
			{
				return null;
			}
			solidBack.Dispose();
			return bmp;
		}

		/// <summary>
		/// This method pick up all fonts installed in system and push them
		/// into the combobox.
		/// </summary>
		private void InitializeFonts()
		{
			FontFamily[] fonts = (new InstalledFontCollection()).Families;
			this.cbFonts.DisplayMember = "Name";
			this.cbFonts.DataSource = fonts;
			this.cbFonts.SelectedIndex = 0;
		}

		/// <summary>
		/// This method pick a filename of destination bitmap font and 
		/// then creates in ASCII order a group of letters.
		/// </summary>
		private void GenerateBitmapFont()
		{
			SaveFileDialog dialog = new SaveFileDialog();
			dialog.FileName = string.Empty;
			dialog.Filter = "Png|*.png";

			if(dialog.ShowDialog() == DialogResult.Cancel)
			{
				return;
			}

			string fileName = dialog.FileName;
			Bitmap bmp = this.GeneratePreview();
			bmp.Save(fileName, ImageFormat.Png);
			MessageBox.Show("Bitmap font was saved to \"" + fileName + "\".", "Saved", MessageBoxButtons.OK, MessageBoxIcon.Information);
		}
		
		/// <summary>
		/// Gets preview
		/// </summary>
		private void GetPreview()
		{
			Bitmap bmp = this.GeneratePreview();
			if (bmp != null)
			{
				this.imPreview.Height = bmp.Height;
				this.imPreview.Width = bmp.Width;
				this.imPreview.Image = bmp;
			}
		}

		#endregion Methods

		private void cbFonts_SelectedIndexChanged(object sender, EventArgs e)
		{
			this.GetPreview();
		}

		private void nuLetterSize_ValueChanged(object sender, EventArgs e)
		{
			this.GetPreview();
		}

		private void button1_Click(object sender, EventArgs e)
		{
			if (colorDialog1.ShowDialog() == DialogResult.OK)
			{
				button1.BackColor = colorDialog1.Color;
			}
		}


	}
}